Tugas Analisis Multimedia: Audio, Gambar, Video¶

Mata Kuliah: Sistem & Teknologi Multimedia
Nama: Naufal Haris Nurkhoirulloh NIM: 122140040


Deskripsi Tugas¶

Tugas ini bertujuan untuk memahami representasi dasar data multimedia (audio, gambar, dan video) melalui praktik langsung memuat data, visualisasi, dan ekstraksi informasi fundamental. Anda akan bekerja dengan tiga jenis media berbeda untuk menganalisis karakteristik temporal (audio), spasial (gambar), dan spatio-temporal (video).

Fokus tugas adalah pada pemahaman konsep dasar representasi multimedia dan kemampuan interpretasi hasil visualisasi, bukan pada manipulasi atau transformasi lanjutan data multimedia.


⚠️ CATATAN PENTING: PRESENTASI ACAK & KEJUJURAN AKADEMIK¶

Sebagian mahasiswa akan dipilih secara ACAK untuk presentasi singkat (5-10 menit) menjelaskan kode dan interpretasi hasil mereka. Jika Anda:

  • Tidak mampu menjelaskan kode yang Anda kumpulkan
  • Hanya menyalin-tempel tanpa pemahaman
  • Bergantung sepenuhnya pada AI tanpa memahami konsep

Maka nilai tugas Anda akan diberikan 0 (nol).

Gunakan referensi dan AI sebagai alat bantu pembelajaran, tetapi pastikan Anda memahami setiap baris kode dan dapat menjelaskan logika di baliknya.

In [1]:
# Import Library (Satu-satunya sel kode dalam template ini)
import numpy as np
import matplotlib.pyplot as plt
import librosa
import soundfile as sf
from PIL import Image
import cv2
from IPython.display import Audio, HTML, display
import os

# Set matplotlib untuk menampilkan plot inline
%matplotlib inline

# Tampilkan versi library untuk dokumentasi
print("Library versions:")
print(f"NumPy: {np.__version__}")
print(f"Matplotlib: {plt.matplotlib.__version__}")
print(f"Librosa: {librosa.__version__}")
print(f"OpenCV: {cv2.__version__}")

# Tambahkan import lain jika diperlukan saat mengerjakan tugas
Library versions:
NumPy: 2.2.5
Matplotlib: 3.10.6
Librosa: 0.11.0
OpenCV: 4.10.0

Petunjuk Umum Pengerjaan¶

📋 Cara Menggunakan Template¶

  • Gunakan notebook ini sebagai kerangka kerja utama
  • Tulis penjelasan (markdown) SEBELUM menaruh kode agar maksud dan tujuan jelas
  • Tambahkan sel kode di tempat yang sudah disediakan (tandai dengan TODO)
  • Semua plot/gambar harus diberi judul, label sumbu, dan keterangan singkat

📊 Standar Visualisasi¶

  • Setiap plot harus memiliki judul yang deskriptif
  • Label sumbu X dan Y harus jelas
  • Gunakan colorbar untuk plot yang memerlukan skala warna
  • Berikan interpretasi singkat setelah setiap visualisasi

📂 Struktur Data yang Direkomendasikan¶

  • Buat folder data/ di direktori yang sama dengan notebook
  • Gunakan nama file yang deskriptif (contoh: audio_musik_piano.wav, gambar_pemandangan_gunung.jpg)
  • Dokumentasikan sumber data jika menggunakan dataset publik

⚠️ Larangan¶

  • Jangan menaruh seluruh pekerjaan dalam satu sel kode yang sangat panjang
  • Jangan menempel hasil output tanpa interpretasi atau analisis
  • Jangan bergantung sepenuhnya pada AI - pahami dan kuasai kode Anda

🎯 Persiapan Presentasi Acak¶

  • Pastikan Anda memahami setiap baris kode yang ditulis
  • Latih menjelaskan logika dan alur pemikiran Anda
  • Siapkan penjelasan untuk setiap visualisasi dan interpretasinya

Checklist Kelengkapan (Centang ✅ saat selesai)¶

🎵 Bagian Audio¶

  • [✅] Muat audio dan tampilkan metadata (durasi, sample rate, jumlah kanal)
  • [✅] Tampilkan waveform dengan label sumbu yang jelas
  • [✅] Tampilkan spectrogram dalam skala log-dB dengan colorbar
  • [✅] Tampilkan MFCC (minimal 13 koefisien) sebagai heatmap
  • [✅] Berikan interpretasi dan analisis untuk setiap visualisasi audio

🖼️ Bagian Gambar¶

  • [✅] Tampilkan gambar dengan benar dalam format RGB
  • [✅] Tampilkan informasi dasar (dimensi, jumlah kanal, dtype)
  • [✅] Tampilkan histogram warna untuk channel R, G, B
  • [✅] Berikan analisis hubungan histogram dengan kesan visual gambar

📹 Bagian Video¶

  • [✅] Tampilkan metadata video (resolusi, fps, frame count, durasi)
  • [✅] Tampilkan 3 frame representatif (awal, tengah, akhir)
  • [✅] Konversi BGR ke RGB dengan benar untuk visualisasi
  • [✅] Analisis kesesuaian parameter video dengan use case

📝 Analisis & Dokumentasi¶

  • [✅] Setiap bagian memiliki interpretasi dan analisis ringkas
  • [✅] Perbandingan representasi ketiga jenis media
  • [✅] Kesimpulan pembelajaran dan refleksi
  • [✅] Semua sumber data dan referensi dicantumkan

Pendahuluan¶

Apa itu Data Multimedia?¶

Data multimedia adalah informasi yang dikodekan dalam berbagai format untuk merepresentasikan dunia nyata:

  • Audio (1D): Sinyal satu dimensi yang berubah terhadap waktu

    • Contoh: musik, suara, speech
    • Representasi: amplitudo vs waktu
  • Gambar (2D): Matriks nilai intensitas dalam ruang dua dimensi

    • Contoh: foto, ilustrasi, grafik
    • Representasi: intensitas pixel pada koordinat (x,y)
  • Video (2D + Waktu): Rangkaian frame (gambar) yang ditampilkan berurutan

    • Contoh: film, rekaman, animasi
    • Representasi: frame berubah terhadap waktu dengan frame rate tertentu

Tujuan Tugas¶

Memahami representasi dasar dan teknik visualisasi fundamental untuk setiap jenis media multimedia, termasuk:

  • Cara memuat dan membaca file multimedia
  • Ekstraksi informasi metadata yang penting
  • Visualisasi yang informatif dan mudah dipahami
  • Interpretasi hasil analisis secara kontekstual

Cara Kerja¶

  1. Isi setiap bagian sesuai instruksi yang diberikan
  2. Tambahkan sel kode di tempat yang ditandai dengan "TODO"
  3. Berikan interpretasi dan analisis setelah setiap visualisasi
  4. Pastikan semua plot memiliki judul, label, dan keterangan yang jelas

Bagian A — Audio¶

A1. Deskripsi Data¶

TODO: Jelaskan audio yang akan Anda analisis:

  • Jenis audio: Suara hujan dengan gemuruh petir
  • Sumber: Dataset Publik (freesound.org)
  • Format file: WAV
  • Alasan pemilihan: Karena saya merasa suara ini menarik untuk dilihat analisisnya dan saya cukup penasaran

Path file: data\rain&thunder.wav


A2. TODO: Muat & Metadata¶

Instruksi: Tulis kode untuk memuat file audio dan menampilkan metadata dasar:

  • Sample rate (Hz)
  • Durasi (detik)
  • Jumlah kanal (mono/stereo)
  • Jumlah total sampel

Catatan: Jika file MP3 bermasalah saat loading, gunakan format WAV sebagai alternatif.

In [2]:
# Muat file audio dan tampilkan metadata dasar
audio_path = os.path.join('data', 'rain&thunder.wav')

# Membaca audio (y: array amplitudo, sr: sample rate)
y, sr = librosa.load(audio_path, sr=None, mono=False)  # mono=False agar bisa deteksi jumlah kanal

# Jika y 1D: mono, jika 2D: stereo/multi-channel
if y.ndim == 1:
  num_channels = 1
  channel_info = 'Mono'
  total_samples = y.shape[0]
else:
  num_channels = y.shape[0]
  channel_info = f'Stereo ({num_channels} channels)' if num_channels == 2 else f'{num_channels} channels'
  total_samples = y.shape[1]

duration_sec = total_samples / sr

print(f"Path file      : {audio_path}")
print(f"Sample rate    : {sr} Hz")
print(f"Durasi         : {duration_sec:.2f} detik")
print(f"Jumlah kanal   : {channel_info}")
print(f"Total sampel   : {total_samples}")
Path file      : data\rain&thunder.wav
Sample rate    : 96000 Hz
Durasi         : 27.07 detik
Jumlah kanal   : Stereo (2 channels)
Total sampel   : 2598291

A3. TODO: Waveform¶

Instruksi: Plot waveform audio dengan:

  • Sumbu X: waktu (detik)
  • Sumbu Y: amplitudo
  • Judul dan label sumbu yang jelas

Analisis yang diperlukan: Jelaskan apa yang Anda lihat dari waveform (pola amplitudo, bagian keras/pelan, dll.)

Analisis pola amplitudo:

Saya melihat perbedaan pola amplitudo pada kanal kanan dan kiri,

  • detik 0-9 terlihat kalau amplitudo keduanya itu relatif rendah dan stabil walaupun tidak sama persis antara keduanya, nah ini adalah suara ambience hujan makanya dia rendah dan stabil.
  • detik 9-17 terlihat kalau amplitudonya mulai melonjak tinggi dan tajam karena disinilah suara gemuruh petirnya, puncak tertinggi amplitudonya itu pada detik 12-13 di kanal kiri hampir mencapai 0.6 sedangkan di kanal kanan hanya sekitar 0.4
  • detik 17-27 amplitudo kembali ke level rendah yang stabil mirip seperti awal yakni suara hujan. Nah saya penasaran kenapa di kanal kanan dan kiri itu berbeda ya, mungkin karena saat merekam suara tersebut kemungkinan besar mikrofon kanal kiri lebih dekat dengan sumber suara (petir) dibanding mikrofon kanan.
In [3]:
# Plot waveform audio untuk masing-masing kanal (stereo)
fig, axs = plt.subplots(num_channels, 1, figsize=(12, 4 * num_channels), sharex=True)

# Buat array waktu (detik)
times = np.arange(total_samples) / sr

channel_names = ['Kanal Kiri (Left)', 'Kanal Kanan (Right)'] if num_channels == 2 else ['Mono']

for i in range(num_channels):
  ax = axs[i] if num_channels > 1 else axs
  ax.plot(times, y[i] if num_channels > 1 else y, color='C0')
  ax.set_ylabel('Amplitudo')
  ax.set_title(f'Waveform Audio - {channel_names[i]}')
  ax.grid(True)

axs[-1].set_xlabel('Waktu (detik)')
plt.tight_layout()
plt.show()

# Tampilkan pemutar audio
display(Audio(audio_path))
No description has been provided for this image
Your browser does not support the audio element.

A4. TODO: Spectrogram log-dB¶

Instruksi: Hitung STFT dan tampilkan spectrogram dalam skala log-dB:

  • Gunakan parameter standar (n_fft=1024, hop_length=256)
  • Tampilkan dengan colorbar
  • Label sumbu: waktu (detik) dan frekuensi (Hz)

Analisis yang diperlukan: Jelaskan perbedaan informasi yang didapat dari spectrogram dibanding waveform.

Compare waveform dengan spectogram:

  • kalau di waveform kita cuma tau sebearap keras dan pelan suara dari amplitudo pada suatu waktu, sedangkan di spectogram kita bisa melihat secara jelas frekuensi tinggi rendahnya pada suatu waktu dan juga melihat warna yang merepresentasikan kekuatan atau amplitudo pada frekuensi tersebut. Jadi spectogram memberikan informasi yang lebih detail tentang komponen frekuensi dalam sinyal audio.
  • Pada spectogram dapat terlihat bahwa suara petir memiliki frekuensi yang lebih rendah dibanding suara hujan yang cenderung memiliki frekuensi yang lebih tinggi. Hal ini bisa dilihat ada warna kuning cerah yang terkonsentrasi dibagian bawah grafik (area frekuensi 64 Hz - 2048 Hz) pada detik 9-17, ini berarti secara visual membuktikan bahwa gemuruh petir suara frekuensi rendah (bass), dibandingkan dengan frekuensi tinggi pada suara hujan (sebelum detik 9 dan setelah detik 17).
  • Disini saya membuat spectogram linear dengan logaritmik, karena telinga manusia itu lebih sensitif terhadap perubahan frekuensi rendah dibanding frekuensi tinggi, jadi dengan skala logaritmik ini kita bisa melihat detail pada frekuensi rendah dengan lebih baik.
  • Lalu kenapa pada spectogram linear itu sampai 48000 Hz? karena sample ratenya adalah 96000 Hz jadi frekuensi tertinggi yang bisa direpresentasikan adalah setengah dari sample rate (Nyquist frequency) yaitu 48000 Hz.
In [4]:
# Parameter STFT sesuai instruksi
n_fft = 1024
hop_length = 256

# ========== SPECTROGRAM 1: Linear Scale (Hz) ==========
print("Membuat Spectrogram dengan skala linear...")

# Buat plot untuk setiap kanal
fig1, axs1 = plt.subplots(num_channels, 1, figsize=(12, 4 * num_channels))

# Jika hanya 1 kanal, axs bukan array
if num_channels == 1:
    axs1 = [axs1]

for i in range(num_channels):
    # Ambil data audio per kanal
    if num_channels == 1:
        audio_data = y
    else:
        audio_data = y[i]
   
    # Hitung STFT
    stft_result = librosa.stft(audio_data, n_fft=n_fft, hop_length=hop_length)
   
    # Konversi ke magnitude dalam dB
    magnitude_db = librosa.amplitude_to_db(np.abs(stft_result), ref=np.max)
   
    # Tampilkan spectrogram
    img1 = librosa.display.specshow(
        magnitude_db,
        sr=sr,
        hop_length=hop_length,
        x_axis='time',    # Label sumbu X: waktu (detik)
        y_axis='hz',      # Label sumbu Y: frekuensi (Hz)
        fmax=10000,       # Batasi frekuensi maksimum ke 10 kHz
        ax=axs1[i]
    )
   
    # Set title dan label
    axs1[i].set_title(f'Spectrogram STFT Linear - {channel_names[i]}')
    axs1[i].set_xlabel('Waktu (detik)')
    axs1[i].set_ylabel('Frekuensi (Hz)')
   
    # Tambahkan colorbar
    cbar1 = fig1.colorbar(img1, ax=axs1[i], format='%+2.0f dB')
    cbar1.set_label('Magnitude (dB)')

# Atur layout dan tampilkan
plt.tight_layout()
plt.show()


# ========== SPECTROGRAM 2: Logarithmic Scale ==========
print("Membuat Spectrogram dengan skala logaritmik...")

# Buat plot kedua dengan skala logaritmik
fig2, axs2 = plt.subplots(num_channels, 1, figsize=(12, 4 * num_channels), sharex=True)

# Jika hanya 1 kanal, axs bukan array
if num_channels == 1:
    axs2 = [axs2]

for idx in range(num_channels):
    # Ambil sinyal per kanal
    y_channel = y[idx] if num_channels > 1 else y
   
    # STFT (menggunakan parameter yang sama)
    D = librosa.stft(y_channel, n_fft=n_fft, hop_length=hop_length)
    S_db = librosa.amplitude_to_db(np.abs(D), ref=np.max)
   
    # Tampilkan spectrogram dengan skala log untuk sumbu y
    img2 = librosa.display.specshow(
        S_db,
        sr=sr,
        hop_length=hop_length,
        x_axis='time',
        y_axis='log',    # Skala logaritmik untuk frekuensi
        ax=axs2[idx],
        fmax=sr//2,      # Batasi frekuensi maksimum (Nyquist frequency)
        vmin=-80,        # Batasi range dB minimum untuk kontras yang lebih baik
        vmax=0           # Batasi range dB maksimum
    )
   
    axs2[idx].set_title(f"Spectrogram STFT Log-dB - {channel_names[idx]}")
    axs2[idx].set_ylabel("Frekuensi (Hz)")
    axs2[idx].set_xlabel("Waktu (detik)")
   
    # Colorbar dengan range yang lebih terbatas
    cbar2 = fig2.colorbar(img2, ax=axs2[idx], format="%+2.0f dB")
    cbar2.set_label('Magnitude (dB)')

plt.tight_layout()
plt.show()


# ========== INFORMASI PARAMETER STFT ==========
print(f"\nParameter STFT yang digunakan:")
print(f"- n_fft: {n_fft}")
print(f"- hop_length: {hop_length}")
print(f"- Resolusi frekuensi: {sr/n_fft:.2f} Hz")
print(f"- Resolusi waktu: {hop_length/sr*1000:.2f} ms")
print(f"- Jumlah kanal: {num_channels}")
print(f"\nDua spectrogram telah dibuat:")
print(f"1. Spectrogram Linear: Skala frekuensi linear (Hz), fmax=10kHz")
print(f"2. Spectrogram Logaritmik: Skala frekuensi log, fmax={sr//2}Hz, range dB: -80 to 0")
Membuat Spectrogram dengan skala linear...
No description has been provided for this image
Membuat Spectrogram dengan skala logaritmik...
No description has been provided for this image
Parameter STFT yang digunakan:
- n_fft: 1024
- hop_length: 256
- Resolusi frekuensi: 93.75 Hz
- Resolusi waktu: 2.67 ms
- Jumlah kanal: 2

Dua spectrogram telah dibuat:
1. Spectrogram Linear: Skala frekuensi linear (Hz), fmax=10kHz
2. Spectrogram Logaritmik: Skala frekuensi log, fmax=48000Hz, range dB: -80 to 0

A5. TODO: MFCC¶

Instruksi: Hitung dan tampilkan minimal 13 koefisien MFCC sebagai heatmap:

  • Sumbu X: waktu (frame)
  • Sumbu Y: koefisien MFCC (1-13)
  • Gunakan colorbar dan judul yang jelas

Analisis yang diperlukan: Interpretasi sederhana: apakah pola MFCC stabil atau berubah-ubah? Apa potensi maknanya?

Analisis MFCC:

  • MFCC adalah singkatan dari Mel-Frequency Cepstral Coefficients. Jika spectrogram adalah "peta" detail dari semua frekuensi dalam suara, maka MFCC adalah rangkuman atau "sidik jari sonik" dari peta tersebut.
  • Berdasarkan MFCC dari audio yang saya analisis ini, polanya dapat dikatakan berubah-ubah. perubahan pada pola MFCC di audio saya merepresentasikan perubahan timbre dari suara hujan ke suara gemuruh petir.
In [5]:
# Hitung MFCC (menggunakan 13 koefisien pertama, sesuai instruksi)
n_mfcc = 13
mfccs = librosa.feature.mfcc(y=audio_data, sr=sr, n_mfcc=n_mfcc, n_fft=n_fft, hop_length=hop_length)

# Plot MFCC sebagai heatmap
plt.figure(figsize=(14, 6))
img = plt.imshow(mfccs, aspect='auto', origin='lower', 
         interpolation='nearest', cmap='viridis',
         extent=[0, mfccs.shape[1], 1, n_mfcc])

plt.title('MFCC (13 Koefisien Pertama) - Audio "Rain & Thunder"')
plt.xlabel('Frame Waktu')
plt.ylabel('Koefisien MFCC')
cbar = plt.colorbar(img, format='%+2.1f')
cbar.set_label('Magnitudo MFCC (dB)')
plt.yticks(np.arange(1, n_mfcc + 1))
plt.tight_layout()
plt.show()
c:\Users\Naufal Haris\.conda\envs\multimedia_env\lib\site-packages\librosa\feature\spectral.py:2148: UserWarning: Empty filters detected in mel frequency basis. Some channels will produce empty responses. Try increasing your sampling rate (and fmax) or reducing n_mels.
  mel_basis = filters.mel(sr=sr, n_fft=n_fft, **kwargs)
No description has been provided for this image

A6. Analisis Ringkas (Wajib)¶

Jawab pertanyaan berikut:

  1. Perbedaan insight: Apa perbedaan informasi yang didapat dari waveform versus spectrogram?

    Kalau waveform hanya menunjukkan perubahan amplitudo (keras/lembut) dari sinyal audio tiap waktu, sehingga informasi yang didapat terbatas pada volume saja. Kita hanya bisa tahu kapan suara besar atau kecil terjadi, tapi tidak tahu frekuensinya.

    Sementara itu, spectrogram memberikan informasi frekuensi secara detail, menunjukkan frekuensi rendah hingga tinggi yang muncul pada tiap waktu serta intensitasnya (melalui warna). Dengan spectrogram, kita bisa membedakan jenis suara berdasarkan pola frekuensinya, misalnya membedakan suara hujan (frekuensi tinggi) dengan petir (frekuensi rendah). Spectrogram memberikan gambaran yang jauh lebih lengkap tentang isi sinyal audio dibanding waveform.

  2. Pembelajaran dari MFCC: Apa yang Anda pelajari dari visualisasi MFCC audio ini?

    Pada visualisasi MFCC, saya belajar bahwa MFCC bisa digunakan untuk menangkap karakteristik suara atau timbre dalam bentuk pola numerik atau visual. Perubahan pola MFCC dalam audio saya menunjukkan adanya perubahan jenis suara, dari hujan yang stabil ke gemuruh petir yang lebih melonjak dan berdampak besar pada spektrum suara. Ini menunjukkan bahwa MFCC efektif untuk mendeteksi perubahan akustik dalam audio, dan dapat digunakan sebagai fitur penting dalam pengenalan suara atau klasifikasi audio.

Bagian B — Gambar¶

B1. Deskripsi Data¶

TODO: Jelaskan gambar yang akan Anda analisis:

  • Jenis gambar: Foto mendaki gunung ratai bersama teman-teman
  • Sumber: Foto sendiri
  • Format file: JPG
  • Alasan pemilihan: Karena saya suka foto ini

Path file: data\koentjie.jpg


B2. TODO: Baca & Tampilkan (RGB)¶

Instruksi: Baca gambar dan tampilkan dengan benar dalam format RGB:

  • Pastikan konversi warna benar (ingat perbedaan BGR vs RGB di OpenCV)
  • Berikan judul yang deskriptif
  • Hilangkan axis untuk tampilan yang bersih

Analisis yang diperlukan: Jelaskan gambar secara ringkas (objek dominan, kondisi pencahayaan, komposisi warna).

Analisis gambar:

  • Objek dominan pada gambar yang saya analisis adalah pada 8 orang mahasiswa yang sedang foto bersama saat mendaki gunung
  • pencahayaannya terang dan alami karena berasal dari cahaya matahari langsung
  • warna dominan adalah hitam berasal dari pakaian mahasiswa tersebut dan warna hijau dari latar belakang hutan atau pepohonan
In [6]:
# Baca gambar dengan OpenCV (untuk output BGR)
img_bgr = cv2.imread('data/koentjie.jpg')
# Baca gambar dengan openCV untuk output RGB
img_rgb = cv2.cvtColor(img_bgr, cv2.COLOR_BGR2RGB)

plt.figure(figsize=(8, 6))
plt.imshow(img_rgb)
plt.title('Foto Mendaki Gunung Ratai Bersama Teman-teman')
plt.axis('off')  # Hilangkan axis
plt.show()
No description has been provided for this image

B3. TODO: Informasi Dasar¶

Instruksi: Tampilkan informasi metadata gambar:

  • Dimensi (Height × Width)
  • Jumlah kanal
  • Tipe data (dtype)
  • Mode warna (jika relevan)
  • Ukuran file dalam memori

Analisis yang diperlukan: Jelaskan mengapa informasi ini penting untuk tahap preprocessing atau analisis lanjutan.

  • Informasi dasar dari metadata gambar sangat penting untuk memastikan gambar siap digunakan untuk analisis atau machine learning. Dengan mengetahui ukuran, kanal, dan tipe data, kita bisa membuat preprocessing yang konsisten, efisien, dan sesuai kebutuhan model.
In [7]:
# Tampilkan metadata gambar
height, width, channels = img_rgb.shape
dtype = img_rgb.dtype
mem_bytes = img_rgb.nbytes
mem_mb = mem_bytes / (1024 * 1024)

# Menentukan mode warna secara dinamis
if channels == 3:
    mode = "RGB"
elif channels == 4:
    mode = "RGBA" # RGB dengan kanal Alpha (transparansi)
elif channels == 1:
    mode = "Grayscale"
else:
    mode = f"{channels} Kanal" # Untuk mode lain yang tidak umum

# Print hasil
print(f"Dimensi (Height × Width) : {height} × {width}")
print(f"Jumlah kanal             : {channels}")
print(f"Tipe data (dtype)        : {dtype}")
print(f"Mode warna               : {mode}")
print(f"Ukuran file di memori    : {mem_mb:.2f} MB")
Dimensi (Height × Width) : 1600 × 1200
Jumlah kanal             : 3
Tipe data (dtype)        : uint8
Mode warna               : RGB
Ukuran file di memori    : 5.49 MB

B4. TODO: Histogram Warna¶

Instruksi: Tampilkan histogram distribusi intensitas untuk channel R, G, B:

  • Range: 0-255
  • Plot terpisah atau overlay dengan warna sesuai channel
  • Label sumbu: intensitas pixel dan frekuensi
  • Legend yang jelas

Analisis yang diperlukan: Analisis: channel mana yang dominan? Bagaimana kontras gambar? Seperti apa sebaran intensitasnya?

Hasil Analisis:

  • Channel yang dominan terlihat pada histogram adalah channel berwarna biru terutama di rentang intensitas gelap sekitar 0-100.
  • Kontras gambar tergolong rendah, karena sebagian besar informasi piksel pada histogram terkonsentrasi di sisi kiri dan tengah, yaitu di wilayah gelap (shadows) dan menengah (midtones).
  • Sebaran intensitas juga terlihat tidak merata karena lebih condong ke arah gelap (sisi kiri), histogram menunjukkan frekuensi yang sangat tinggi di rentang intensitas rendah (sekitar 0-50), yang kemudian menurun secara drastis seiring dengan meningkatnya intensitas.
In [8]:
# Plot histogram distribusi intensitas untuk channel R, G, B
colors = ['red', 'green', 'blue']
channel_labels = ['Red', 'Green', 'Blue']

plt.figure(figsize=(10, 6))
for i, color in enumerate(colors):
  plt.hist(
    img_rgb[..., i].ravel(),
    bins=256,
    range=(0, 255),
    color=color,
    alpha=0.6,
    label=channel_labels[i]
  )

plt.title('Histogram Distribusi Intensitas Warna (R, G, B)')
plt.xlabel('Intensitas Pixel (0-255)')
plt.ylabel('Frekuensi')
plt.legend()
plt.grid(True, linestyle='--', alpha=0.3)
plt.tight_layout()
plt.show()
No description has been provided for this image

B5. Analisis Ringkas (Wajib)¶

Jawab pertanyaan berikut:

Relasi histogram dengan kesan visual: Apa hubungan antara pola histogram yang Anda lihat dengan kesan visual gambar (terang/gelap, warna dominan, kontras)?

Pola histogram menunjukkan bahwa sebagian besar intensitas pixel berada pada intensitas rendah (0–100), dengan frekuensi yang sangat tinggi di rentang 0–50, khususnya pada channel biru. Hal ini menggambarkan bahwa gambar secara umum memiliki kesan gelap atau berada dalam lingkungan teduh, yang konsisten dengan konteks visual foto yang diambil di area hutan.

Dominasi warna biru pada histogram mendukung kesan visual gambar yang memiliki nuansa dingin. Sementara itu, adanya sedikit lonjakan pada intensitas tinggi (sekitar 255) menunjukkan bahwa ada beberapa area terang, kemungkinan cahaya matahari yang menembus dedaunan, tetapi tidak mendominasi gambar.

Kontras gambar cenderung rendah hingga sedang, karena distribusi piksel terkonsentrasi di intensitas rendah tanpa penyebaran merata ke seluruh rentang 0–255.

Bagian C — Video¶

C1. Deskripsi Data¶

TODO: Jelaskan video yang akan Anda analisis:

  • Jenis video: Aktivitas bermain billiard dengan teman-teman
  • Sumber: Rekaman sendiri
  • Durasi target: 16 detik
  • Alasan pemilihan: Karena mudah ketemu di galeri

Path file: data\koentjie.mp4 koent

C2. TODO: Baca & Metadata¶

Instruksi: Baca video dengan OpenCV dan tampilkan metadata:

  • Resolusi (Width × Height)
  • Frame rate (fps)
  • Jumlah total frame
  • Durasi (detik)
  • Klasifikasi resolusi (HD, Full HD, 4K, dll.)

Analisis yang diperlukan: Jelaskan pentingnya parameter-parameter tersebut untuk analisis video atau aplikasi tertentu.

Metadata video seperti resolusi, frame rate, jumlah frame, durasi, dan klasifikasi resolusi sangat penting karena mereka mendefinisikan skala, kualitas, dan kompleksitas data video. Resolusi menentukan seberapa detail gambar yang bisa dianalisis—semakin tinggi, semakin tajam, tapi juga semakin berat diproses. Frame rate memengaruhi kelancaran dan keakuratan pelacakan gerakan; fps tinggi dibutuhkan untuk momen cepat agar tidak terlewat. Jumlah total frame dan durasi memberi gambaran seberapa besar dan lama proses analisis akan berlangsung, penting untuk estimasi waktu dan sumber daya. Klasifikasi resolusi seperti HD atau 4K membantu dalam standardisasi dan pengambilan keputusan cepat terkait kualitas dan kebutuhan komputasi. Intinya, metadata ini adalah peta awal untuk memahami video sebelum dianalisis lebih dalam.

In [9]:
# Tentukan path ke file video
video_path = 'data/koentjie.mp4'

# Buka video menggunakan VideoCapture
cap = cv2.VideoCapture(video_path)

# Periksa apakah video berhasil dibuka
if not cap.isOpened():
    print(f"Error: Tidak bisa membuka file video di '{video_path}'")
    sys.exit()

# 1. Resolusi (Width & Height)
# Ambil properti lebar dan tinggi frame, lalu konversi ke integer
width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))

# 2. Frame Rate (fps)
# Ambil properti FPS (Frames Per Second)
fps = cap.get(cv2.CAP_PROP_FPS)

# 3. Jumlah Total Frame
# Ambil properti jumlah total frame dalam video
total_frames = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))

# 4. Durasi (detik)
# Hitung durasi dengan membagi total frame dengan fps
# Tambahkan pengecekan untuk menghindari pembagian dengan nol jika fps tidak valid
duration = 0
if fps > 0:
    duration = total_frames / fps
else:
    duration = "Tidak dapat dihitung (FPS = 0)"


# 5. Klasifikasi Resolusi
# Tentukan klasifikasi berdasarkan lebar (width) video
if width >= 3840:
    resolution_class = "4K (Ultra HD)"
elif width >= 2560:
    resolution_class = "QHD (2K)"
elif width >= 1920:
    resolution_class = "Full HD (FHD)"
elif width >= 1280:
    resolution_class = "HD"
else:
    resolution_class = "SD (Standard Definition)"


# --- Tampilkan Hasil Metadata ---
print("===== METADATA VIDEO =====")
print(f"Lokasi File         : {video_path}")
print(f"Resolusi            : {width} × {height} pixels")
print(f"Frame Rate (FPS)    : {fps:.2f} fps")
print(f"Jumlah Total Frame  : {total_frames} frames")
if isinstance(duration, float):
    print(f"Durasi              : {duration:.2f} detik")
else:
    print(f"Durasi              : {duration}")

print(f"Klasifikasi Resolusi: {resolution_class}")

# Jangan lupa untuk melepaskan object capture setelah selesai
cap.release()
===== METADATA VIDEO =====
Lokasi File         : data/koentjie.mp4
Resolusi            : 478 × 850 pixels
Frame Rate (FPS)    : 25.00 fps
Jumlah Total Frame  : 606 frames
Durasi              : 24.24 detik
Klasifikasi Resolusi: SD (Standard Definition)

C3. TODO: Tampilkan 3 Frame (Awal–Tengah–Akhir)¶

Instruksi: Ambil dan tampilkan 3 frame representatif:

  • Frame pertama (index 0)
  • Frame tengah (index ~total_frame/2)
  • Frame terakhir (index total_frame-1)
  • Konversi BGR→RGB sebelum ditampilkan
  • Subplot dengan judul frame dan timestamp

Analisis yang diperlukan: Deskripsikan perbedaan visual antar frame dan apa yang dapat dipelajari dari sampel frame ini.

Analisis frame:

  • Frame awal: menampilkan suasana siang hari di atas perahu tengah laut, dan ada saya yang sedang duduk dipinggir badan perahu

  • Frame tengah : menunjukkan kalau sudah sampai daratan dan baru selesai membangun tenda

  • Frame Akhir: menunjukkan perubahan waktu yaitu pada malam hari dan sepertinya di tepi laut karena terlihat siluet atau tangan seseorang memegang alat pancing yang berarti dia sedang memancing.

  • saya mempelajari bahwa frame tersebut menunjukkan alur cerita orang yang pergi ke suatu pulau dengan perahu kemudian membangun tenda untuk berkemah dan memancing pada malam harinya. ini berarti hanya dengan 3 frame ini saja kita sudah bisa mendapat gambaran besar keseluruhan isi video.

In [22]:
# Tentukan path ke file video
video_path = 'data/koentjie.mp4'

# Buka video menggunakan VideoCapture
cap = cv2.VideoCapture(video_path)

# Periksa apakah video berhasil dibuka
if not cap.isOpened():
    print(f"Error: Tidak bisa membuka file video di '{video_path}'")
else:
    # Ambil metadata yang diperlukan
    fps = cap.get(cv2.CAP_PROP_FPS)
    total_frames = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))
    
    print(f"Total frames: {total_frames}, FPS: {fps}")

    # PERBAIKAN: Kurangi frame akhir dengan buffer lebih besar
    frame_akhir_safe = max(0, total_frames - 2)  # Buffer 2 frame dari akhir
    
    # Tentukan indeks dan timestamp untuk setiap frame
    ts_tengah = (total_frames / 2) / fps if fps > 0 else 0
    ts_akhir = frame_akhir_safe / fps if fps > 0 else 0

    frame_info = {
        "Frame Awal": {"index": 0, "timestamp": 0.0},
        "Frame Tengah": {"index": int(total_frames / 2), "timestamp": ts_tengah},
        "Frame Akhir": {"index": frame_akhir_safe, "timestamp": ts_akhir}
    }

    # Siapkan subplot untuk menampilkan 3 gambar
    fig, axes = plt.subplots(1, 3, figsize=(18, 6))
    
    # Loop melalui informasi frame yang sudah kita siapkan
    for i, (title, info) in enumerate(frame_info.items()):
        print(f"Mencoba membaca {title} - Frame #{info['index']}")
        
        # PERBAIKAN: Cek apakah index valid
        if info["index"] >= total_frames:
            print(f"Warning: Index {info['index']} melebihi total frames {total_frames}")
            info["index"] = total_frames - 20  # Fallback ke 20 frame sebelum akhir
        
        # Lompat ke frame yang diinginkan
        success = cap.set(cv2.CAP_PROP_POS_FRAMES, info["index"])
        if not success:
            print(f"Gagal set posisi frame untuk {title}")
            continue
        
        # Baca frame
        ret, frame = cap.read()
        
        if ret and frame is not None:
            # Langkah KRUSIAL: Konversi BGR (OpenCV) -> RGB (Matplotlib)
            frame_rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
            
            # Tampilkan frame di subplot yang sesuai
            axes[i].imshow(frame_rgb)
            
            # Buat judul yang informatif dengan timestamp
            judul = f"{title}\n(Frame #{info['index']}, Detik: {info['timestamp']:.2f}s)"
            axes[i].set_title(judul, fontsize=12)
            
            print(f"✓ Berhasil membaca {title}")
        else:
            print(f"✗ Gagal membaca {title}")
            axes[i].text(0.5, 0.5, f"Gagal membaca\n{title}", 
                        ha='center', va='center', transform=axes[i].transAxes)
            axes[i].set_title(f"Gagal membaca {title}")
        
        # Hilangkan sumbu x dan y untuk tampilan yang lebih bersih
        axes[i].axis('off')

    # Atur layout agar rapi dan tampilkan plot
    plt.tight_layout()
    plt.show()

# Jangan lupa untuk melepaskan object capture setelah selesai
cap.release()
Total frames: 606, FPS: 25.0
Mencoba membaca Frame Awal - Frame #0
✓ Berhasil membaca Frame Awal
Mencoba membaca Frame Tengah - Frame #303
✓ Berhasil membaca Frame Tengah
Mencoba membaca Frame Akhir - Frame #604
✓ Berhasil membaca Frame Akhir
No description has been provided for this image

C4. Analisis Ringkas (Wajib)¶

Jawab pertanyaan berikut:

Kesesuaian parameter: Apakah fps dan resolusi video ini sesuai untuk use case pilihan Anda (misalnya: media sosial, kuliah daring, presentasi, dll.)? Jelaskan alasan singkat.

Ya, fps dan resolusi video ini sesuai untuk use case seperti media sosial. Dengan resolusi 478×850 piksel (vertikal) dan frame rate 25 fps, video ini sudah cukup untuk ditampilkan secara nyaman di platform seperti Instagram Reels/story, TikTok, atau YouTube Shorts, yang memang dirancang untuk konten vertikal dengan durasi pendek.

Perbandingan & Kesimpulan¶

Perbandingan Representasi Media¶

TODO: Bandingkan secara ringkas representasi dan visualisasi ketiga media:

Audio (1D - Temporal)¶

  • Representasi: Nilai amplitudo pada kanal kiri dan kanan berbeda terutama pada puncak amplitudonya.
  • Visualisasi utama: Waveform, Spectogram, dan MFCC(Mel-Frequency Cepstral Coefficients)
  • Informasi yang diperoleh: saya mengerti kalau waveform digunakan untuk melihat keras atau pelannya suara pada tiap waktu dengan melihat amplitudo pada waktu tertentu, kalau spectogram itu sama namun dengan tambahan frekuensi dimana petir itu frekuensinya rendah (bass) makanya dia terang dibagian bawah grafik berbeda dengan hujan yang frekuensinya tinggi.

Gambar (2D - Spasial)¶

  • Representasi: Matriks pixel dua dimensi dari citra berwarna (RGB) dimana setiap nilai intensitas pixel merepresentasikan warna, kontras, atau kondisi pencahayaan suatu gambar.
  • Visualisasi utama: citra digital berupa foto pendakian, dan histogram
  • Informasi yang diperoleh: Dari citra, diperoleh informasi seperti lokasi (hutan/lembab), aktivitas (pendakian), dan objek utama (manusia, vegetasi). Sementara dari histogram, diperoleh statistik tentang distribusi intensitas warna, yang menunjukkan dominasi warna gelap (khususnya biru), pencahayaan cenderung rendah, serta kontras yang tidak terlalu tinggi.

Video (2D + Waktu - Spatio-temporal)¶

  • Representasi: Representasi urutan frame dua dimensi dalam waktu, yang merekam perubahan visual secara dinamis pada durasi sekitar 24 detik dengan resolusi SD (478 × 850 pixels) dan frame rate 25 fps.
  • Visualisasi utama: Frame awal, tengah, dan akhir.
  • Informasi yang diperoleh: Informasi spasial dan temporal seperti transisi waktu (siang ke malam), pergerakan objek (orang, lingkungan), serta perubahan pencahayaan dan warna. Frame awal menunjukkan suasana cerah di perairan, frame tengah menampilkan aktivitas di pantai dengan tenda, dan frame akhir memperlihatkan kondisi malam hari dengan pencahayaan minim.

Refleksi Pembelajaran¶

3 Poin yang Saya Pelajari:¶

  1. Waveform dan spectrogram memiliki fungsi yang berbeda namun saling melengkapi untuk menganalisis sinyal audio. Waveform menunjukkan perubahan amplitudo sinyal terhadap waktu, memberikan gambaran kasar tentang pola suara dan volume. Spectrogram menampilkan frekuensi sinyal sepanjang waktu, penting untuk mengenali karakter suara, nada, dan pola frekuensi.
  2. Histogram distribusi warna penting untuk memahami intensitas piksel dan kontras gambar. Channel warna yang dominan pada gambar bisa menunjukkan warna utama yang mendominasi visual dan mood gambar.
  3. Metadata seperti resolusi, frame rate, dan durasi sangat penting untuk memahami kualitas dan skala data video. Resolusi video memengaruhi detail visual yang dapat dianalisis, sementara frame rate memengaruhi kelancaran dan ketepatan analisis gerakan.

2 Hal yang Masih Membingungkan/Ingin Diperdalam:¶

  1. jujur saya masih lumayan bingung dengan MFCC bahkan setelah saya pelajari masih kurang paham, mungkin nanti saya gali sendiri
  2. Apakah pada video frame akhir itu bisa tampilkan tanpa harus mengurangi jumlah frame, saya sudah otak atik dan ketemu di buffer 2 frame akhir baru bisa tampil. nanti akan saya coba lagi

Sumber Data & Referensi¶

TODO: Cantumkan semua sumber data dan referensi yang digunakan:

  • Audio: https://freesound.org/people/klankbeeld/sounds/826435/
  • Gambar: Foto sendiri
  • Video: Rekaman sendiri
  • Referensi teknis: Gemini (https://g.co/gemini/share/5b28680b4f4f)

Rubrik Penilaian¶

Distribusi Bobot Penilaian¶

Aspek Penilaian Bobot Deskripsi
Kelengkapan 35% Semua langkah inti dikerjakan sesuai checklist
Kualitas Visualisasi 20% Judul, label sumbu, colorbar, legend, keterbacaan plot
Analisis & Interpretasi 30% Kemampuan interpretasi hasil, bukan sekadar output mentah
Kerapihan & Struktur 10% Markdown jelas, kode modular, dokumentasi baik
Orisinalitas & Penguasaan 5% Pemahaman saat presentasi acak

Detail Kriteria Penilaian¶

🏆 Kelengkapan (35%)¶

  • ✅ Semua 4 visualisasi audio (metadata, waveform, spectrogram, MFCC)
  • ✅ Semua 3 visualisasi gambar (display RGB, metadata, histogram)
  • ✅ Semua 2 visualisasi video (metadata, frame extraction)
  • ✅ Analisis ringkas untuk setiap bagian

📊 Kualitas Visualisasi (20%)¶

  • Plot memiliki judul yang informatif dan deskriptif
  • Label sumbu X dan Y jelas dan sesuai
  • Colorbar/legend tersedia jika diperlukan
  • Ukuran plot proporsional dan mudah dibaca

🧠 Analisis & Interpretasi (30%)¶

  • Interpretasi menunjukkan pemahaman konsep
  • Analisis kontekstual, bukan sekadar deskripsi output
  • Mampu menghubungkan hasil dengan teori
  • Refleksi pembelajaran yang thoughtful

📝 Kerapihan & Struktur (10%)¶

  • Markdown terstruktur dengan heading yang konsisten
  • Kode bersih, terkompartemen, dan mudah dibaca
  • Dokumentasi yang memadai
  • Flow logical dari satu bagian ke bagian lain

🎯 Orisinalitas & Penguasaan (5%)¶

  • PENTING: Jika saat presentasi acak Anda tidak mampu menjelaskan kode yang Anda tulis atau menunjukkan ketergantungan buta pada AI/copy-paste, nilai tugas akan dianggap 0.
  • Kemampuan menjelaskan logika dan alur pemikiran
  • Pemahaman konsep di balik implementasi kode

Proporsi Penilaian Total¶

  • Proporsi penilaian hanya 80%, 20% lagi akan didasarkan pada kecepatan pengumpulan tugas
  • Sehingga: 0.8 * penilaian dosen + nilai waktu pengumpulan

Aturan Kejujuran Akademik¶

📖 Penggunaan Referensi & AI yang Diperbolehkan¶

Anda BOLEH menggunakan:

  • ✅ Dokumentasi resmi library (NumPy, Matplotlib, Librosa, OpenCV)
  • ✅ Tutorial dan contoh kode dari sumber terpercaya
  • ✅ AI tools (ChatGPT, GitHub Copilot, dll.) sebagai alat bantu pembelajaran
  • ✅ Diskusi dengan teman untuk pemahaman konsep

⚠️ Syarat & Batasan WAJIB¶

Namun Anda HARUS:

  • 🧠 Memahami setiap baris kode yang Anda masukkan ke notebook
  • 📝 Menulis interpretasi dengan kata-kata sendiri, bukan hasil copy-paste
  • 📚 Mencantumkan sumber data dan referensi yang digunakan, termasuk transkrip percakapan dengan AI dalam link atau teks
  • 🎯 Mampu menjelaskan logika dan alur pemikiran saat presentasi acak

❌ Pelanggaran yang Berakibat Nilai 0¶

  • Plagiarisme atau penyalinan buta dari sumber manapun
  • Copy-paste kode tanpa pemahaman dan tidak dapat menjelaskan
  • Menggunakan AI untuk mengerjakan seluruh tugas tanpa pembelajaran personal
  • Tidak dapat menjawab pertanyaan dasar tentang kode yang dikumpulkan
  • Menyalin pekerjaan teman atau bekerjasama dalam pengerjaan individual

🎯 Persiapan Presentasi Acak¶

Kemungkinan pertanyaan yang akan ditanyakan:

  • "Jelaskan mengapa Anda menggunakan parameter ini di STFT?"
  • "Apa arti dari pola yang terlihat di MFCC?"
  • "Mengapa perlu konversi BGR ke RGB?"
  • "Interpretasikan hasil histogram yang Anda buat"
  • "Bagaimana cara kerja spectrogram?"

Tips sukses:

  • Pahami konsep dasar setiap teknik yang digunakan
  • Latih menjelaskan dengan bahasa sederhana
  • Siapkan justifikasi untuk setiap pilihan parameter
  • Kuasai interpretasi setiap visualisasi yang dibuat

Panduan Pengumpulan¶

📁 Berkas yang Harus Dikumpulkan¶

Wajib:¶

  1. Notebook Jupyter (.ipynb) dengan nama: NIM_Nama_TugasMultimedia.ipynb
    • Contoh: 123456789_JohnDoe_TugasMultimedia.ipynb
  2. PDF hasil render dari notebook

📅 Informasi Pengumpulan¶


✅ Checklist Sebelum Submit¶

  • [✅] Semua cell sudah dijalankan dan menampilkan output
  • [✅] Nama file sesuai format: NIM_Worksheet2.ipynb dan NIM_Worksheet2.pdf
  • [✅] Semua TODO sudah diisi dengan lengkap
  • [✅] Analisis dan interpretasi sudah ditulis untuk setiap bagian
  • [✅] Sumber data dan referensi sudah dicantumkan

Export ke PDF:¶

  • File → Save and Export Notebook As → HTML
  • Buka HTML di browser -> Save as PDF